home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / ubiquity / install.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  61.0 KB  |  2,091 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import sys
  5. import os
  6. import platform
  7. import errno
  8. import stat
  9. import re
  10. import textwrap
  11. import shutil
  12. import subprocess
  13. import time
  14. import struct
  15. import socket
  16. import fcntl
  17. import traceback
  18. import syslog
  19. import gzip
  20. import debconf
  21. import warnings
  22. warnings.filterwarnings('ignore', 'apt API not stable yet', FutureWarning)
  23. import apt_pkg
  24. from apt.cache import Cache
  25. from apt.progress import FetchProgress, InstallProgress
  26. from hashlib import md5
  27. sys.path.insert(0, '/usr/lib/ubiquity')
  28. from ubiquity import misc
  29. from ubiquity import osextras
  30. from ubiquity.components import language_apply, apt_setup, timezone_apply, clock_setup, console_setup_apply, usersetup_apply, hw_detect, check_kernels, migrationassistant_apply
  31.  
  32. def debconf_disconnect():
  33.     '''Disconnect from debconf. This is only to be used as a subprocess
  34.     preexec_fn helper.'''
  35.     os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
  36.     if 'DEBIAN_HAS_FRONTEND' in os.environ:
  37.         del os.environ['DEBIAN_HAS_FRONTEND']
  38.     
  39.     if 'DEBCONF_USE_CDEBCONF' in os.environ:
  40.         del os.environ['DEBCONF_USE_CDEBCONF']
  41.     
  42.  
  43.  
  44. class DebconfFetchProgress(FetchProgress):
  45.     """An object that reports apt's fetching progress using debconf."""
  46.     
  47.     def __init__(self, db, title, info_starting, info):
  48.         FetchProgress.__init__(self)
  49.         self.db = db
  50.         self.title = title
  51.         self.info_starting = info_starting
  52.         self.info = info
  53.         self.old_capb = None
  54.         self.eta = 0
  55.  
  56.     
  57.     def start(self):
  58.         self.db.progress('START', 0, 100, self.title)
  59.         if self.info_starting is not None:
  60.             self.db.progress('INFO', self.info_starting)
  61.         
  62.         self.old_capb = self.db.capb()
  63.         capb_list = self.old_capb.split()
  64.         capb_list.append('progresscancel')
  65.         self.db.capb(' '.join(capb_list))
  66.  
  67.     
  68.     def pulse(self):
  69.         FetchProgress.pulse(self)
  70.         
  71.         try:
  72.             self.db.progress('SET', int(self.percent))
  73.         except debconf.DebconfError:
  74.             return False
  75.  
  76.         if self.eta != 0:
  77.             time_str = '%d:%02d' % divmod(int(self.eta), 60)
  78.             self.db.subst(self.info, 'TIME', time_str)
  79.             
  80.             try:
  81.                 self.db.progress('INFO', self.info)
  82.             except debconf.DebconfError:
  83.                 return False
  84.             
  85.  
  86.         None<EXCEPTION MATCH>debconf.DebconfError
  87.         return True
  88.  
  89.     
  90.     def stop(self):
  91.         if self.old_capb is not None:
  92.             self.db.capb(self.old_capb)
  93.             self.old_capb = None
  94.             self.db.progress('STOP')
  95.         
  96.  
  97.  
  98.  
  99. class DebconfInstallProgress(InstallProgress):
  100.     """An object that reports apt's installation progress using debconf."""
  101.     
  102.     def __init__(self, db, title, info, error = None):
  103.         InstallProgress.__init__(self)
  104.         self.db = db
  105.         self.title = title
  106.         self.info = info
  107.         self.error_template = error
  108.         self.started = False
  109.         flags = fcntl.fcntl(self.statusfd.fileno(), fcntl.F_GETFL)
  110.         fcntl.fcntl(self.statusfd.fileno(), fcntl.F_SETFL, flags & ~(os.O_NONBLOCK))
  111.  
  112.     
  113.     def startUpdate(self):
  114.         self.db.progress('START', 0, 100, self.title)
  115.         self.started = True
  116.  
  117.     
  118.     def error(self, pkg, errormsg):
  119.         if self.error_template is not None:
  120.             self.db.subst(self.error_template, 'PACKAGE', pkg)
  121.             self.db.subst(self.error_template, 'MESSAGE', errormsg)
  122.             self.db.input('critical', self.error_template)
  123.             self.db.go()
  124.         
  125.  
  126.     
  127.     def statusChange(self, pkg, percent, status):
  128.         self.percent = percent
  129.         self.status = status
  130.         self.db.progress('SET', int(percent))
  131.         self.db.subst(self.info, 'DESCRIPTION', status)
  132.         self.db.progress('INFO', self.info)
  133.  
  134.     
  135.     def updateInterface(self):
  136.         if self.statusfd is None:
  137.             return False
  138.         
  139.         try:
  140.             while not self.read.endswith('\n'):
  141.                 r = os.read(self.statusfd.fileno(), 1)
  142.                 if not r:
  143.                     return False
  144.                 self.read += r
  145.                 continue
  146.                 self
  147.         except OSError:
  148.             self.statusfd is None
  149.             (err, errstr) = self.statusfd is None
  150.             print errstr
  151.         except:
  152.             self.statusfd is None
  153.  
  154.         return True
  155.  
  156.     
  157.     def run(self, pm):
  158.         child_pid = self.fork()
  159.         if child_pid == 0:
  160.             os.close(self.writefd)
  161.             
  162.             try:
  163.                 while self.updateInterface():
  164.                     pass
  165.             except (KeyboardInterrupt, SystemExit):
  166.                 pass
  167.             except:
  168.                 for line in traceback.format_exc().split('\n'):
  169.                     syslog.syslog(syslog.LOG_WARNING, line)
  170.                 
  171.  
  172.             os._exit(0)
  173.         
  174.         self.statusfd.close()
  175.         saved_stdin = os.dup(0)
  176.         
  177.         try:
  178.             null = os.open('/dev/null', os.O_RDONLY)
  179.             os.dup2(null, 0)
  180.             os.close(null)
  181.         except OSError:
  182.             pass
  183.  
  184.         saved_stdout = os.dup(1)
  185.         os.dup2(2, 1)
  186.         saved_environ_keys = ('DEBIAN_FRONTEND', 'DEBIAN_HAS_FRONTEND', 'DEBCONF_USE_CDEBCONF')
  187.         saved_environ = { }
  188.         for key in saved_environ_keys:
  189.             if key in os.environ:
  190.                 saved_environ[key] = os.environ[key]
  191.                 continue
  192.         
  193.         os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
  194.         if 'DEBIAN_HAS_FRONTEND' in os.environ:
  195.             del os.environ['DEBIAN_HAS_FRONTEND']
  196.         
  197.         if 'DEBCONF_USE_CDEBCONF' in os.environ:
  198.             del os.environ['DEBCONF_USE_CDEBCONF']
  199.         
  200.         res = pm.ResultFailed
  201.         
  202.         try:
  203.             res = pm.DoInstall(self.writefd)
  204.         finally:
  205.             os.close(self.writefd)
  206.             while True:
  207.                 
  208.                 try:
  209.                     (pid, status) = os.waitpid(child_pid, 0)
  210.                     if pid != child_pid:
  211.                         break
  212.                     
  213.                     if os.WIFEXITED(status) or os.WIFSIGNALED(status):
  214.                         break
  215.                 continue
  216.                 except OSError:
  217.                     break
  218.                     continue
  219.                 
  220.  
  221.                 None<EXCEPTION MATCH>OSError
  222.             os.dup2(saved_stdin, 0)
  223.             os.close(saved_stdin)
  224.             os.dup2(saved_stdout, 1)
  225.             os.close(saved_stdout)
  226.             for key in saved_environ_keys:
  227.                 if key in saved_environ:
  228.                     os.environ[key] = saved_environ[key]
  229.                     continue
  230.                 if key in os.environ:
  231.                     del os.environ[key]
  232.                     continue
  233.             
  234.  
  235.         return res
  236.  
  237.     
  238.     def finishUpdate(self):
  239.         if self.started:
  240.             self.db.progress('STOP')
  241.             self.started = False
  242.         
  243.  
  244.  
  245.  
  246. class InstallStepError(Exception):
  247.     '''Raised when an install step fails.'''
  248.     
  249.     def __init__(self, message):
  250.         Exception.__init__(self, message)
  251.  
  252.  
  253.  
  254. class Install:
  255.     
  256.     def __init__(self):
  257.         '''Initial attributes.'''
  258.         if os.path.isdir('/rofs'):
  259.             self.source = '/rofs'
  260.         elif os.path.isdir('/UNIONFS'):
  261.             self.source = '/UNIONFS'
  262.         else:
  263.             self.source = '/var/lib/ubiquity/source'
  264.         self.target = '/target'
  265.         self.kernel_version = platform.release()
  266.         self.db = debconf.Debconf()
  267.         self.select_language_packs()
  268.         use_restricted = True
  269.         
  270.         try:
  271.             if self.db.get('apt-setup/restricted') == 'false':
  272.                 use_restricted = False
  273.         except debconf.DebconfError:
  274.             pass
  275.  
  276.         if not use_restricted:
  277.             self.restricted_cache = Cache()
  278.         
  279.         self.blacklist = { }
  280.         if self.db.get('ubiquity/install/generate-blacklist') == 'true':
  281.             self.db.progress('START', 0, 100, 'ubiquity/install/title')
  282.             self.db.progress('INFO', 'ubiquity/install/blacklist')
  283.             self.generate_blacklist()
  284.         
  285.         apt_pkg.InitConfig()
  286.         apt_pkg.Config.Set('Dir', '/target')
  287.         apt_pkg.Config.Set('Dir::State::status', '/target/var/lib/dpkg/status')
  288.         apt_pkg.Config.Set('APT::GPGV::TrustedKeyring', '/target/etc/apt/trusted.gpg')
  289.         apt_pkg.Config.Set('Acquire::gpgv::Options::', '--ignore-time-conflict')
  290.         apt_pkg.Config.Set('DPkg::Options::', '--root=/target')
  291.         apt_pkg.Config.Clear('DPkg::Pre-Install-Pkgs')
  292.         apt_pkg.InitSystem()
  293.  
  294.     
  295.     def excepthook(self, exctype, excvalue, exctb):
  296.         '''Crash handler. Dump the traceback to a file so that it can be
  297.         read by the caller.'''
  298.         if issubclass(exctype, KeyboardInterrupt) or issubclass(exctype, SystemExit):
  299.             return None
  300.         tbtext = ''.join(traceback.format_exception(exctype, excvalue, exctb))
  301.         syslog.syslog(syslog.LOG_ERR, 'Exception during installation:')
  302.         for line in tbtext.split('\n'):
  303.             syslog.syslog(syslog.LOG_ERR, line)
  304.         
  305.         tbfile = open('/var/lib/ubiquity/install.trace', 'w')
  306.         print >>tbfile, tbtext
  307.         tbfile.close()
  308.         sys.exit(1)
  309.  
  310.     
  311.     def run(self):
  312.         '''Run the install stage: copy everything to the target system, then
  313.         configure it as necessary.'''
  314.         self.db.progress('START', 0, 100, 'ubiquity/install/title')
  315.         self.db.progress('INFO', 'ubiquity/install/mounting_source')
  316.         
  317.         try:
  318.             if self.source == '/var/lib/ubiquity/source':
  319.                 self.mount_source()
  320.             
  321.             self.db.progress('SET', 1)
  322.             self.db.progress('REGION', 1, 75)
  323.             
  324.             try:
  325.                 self.copy_all()
  326.             except EnvironmentError:
  327.                 e = None
  328.                 if e.errno in (errno.ENOENT, errno.EIO, errno.EFAULT, errno.ENOTDIR, errno.EROFS):
  329.                     if e.filename is None:
  330.                         error_template = 'cd_hd_fault'
  331.                     elif e.filename.startswith('/target'):
  332.                         error_template = 'hd_fault'
  333.                     else:
  334.                         error_template = 'cd_fault'
  335.                     error_template = 'ubiquity/install/copying_error/%s' % error_template
  336.                     self.db.subst(error_template, 'ERROR', str(e))
  337.                     self.db.input('critical', error_template)
  338.                     self.db.go()
  339.                     sys.exit(3)
  340.                 elif e.errno == errno.ENOSPC:
  341.                     error_template = 'ubiquity/install/copying_error/no_space'
  342.                     self.db.subst(error_template, 'ERROR', str(e))
  343.                     self.db.input('critical', error_template)
  344.                     self.db.go()
  345.                     sys.exit(3)
  346.                 else:
  347.                     raise 
  348.                 e.errno in (errno.ENOENT, errno.EIO, errno.EFAULT, errno.ENOTDIR, errno.EROFS)
  349.  
  350.             self.db.progress('SET', 75)
  351.             self.db.progress('REGION', 75, 76)
  352.             self.db.progress('INFO', 'ubiquity/install/locales')
  353.             self.configure_locales()
  354.             self.db.progress('SET', 76)
  355.             self.db.progress('REGION', 76, 77)
  356.             self.db.progress('INFO', 'ubiquity/install/user')
  357.             self.configure_user()
  358.             self.db.progress('SET', 77)
  359.             self.db.progress('REGION', 77, 78)
  360.             self.run_target_config_hooks()
  361.             self.db.progress('SET', 78)
  362.             self.db.progress('REGION', 78, 79)
  363.             self.db.progress('INFO', 'ubiquity/install/network')
  364.             self.configure_network()
  365.             self.db.progress('SET', 79)
  366.             self.db.progress('REGION', 79, 80)
  367.             self.db.progress('INFO', 'ubiquity/install/apt')
  368.             self.configure_apt()
  369.             self.db.progress('SET', 80)
  370.             self.db.progress('REGION', 80, 85)
  371.             
  372.             try:
  373.                 self.install_language_packs()
  374.             except InstallStepError:
  375.                 pass
  376.             except IOError:
  377.                 pass
  378.             except SystemError:
  379.                 pass
  380.  
  381.             self.db.progress('SET', 85)
  382.             self.db.progress('REGION', 85, 86)
  383.             self.db.progress('INFO', 'ubiquity/install/timezone')
  384.             self.configure_timezone()
  385.             self.db.progress('SET', 86)
  386.             self.db.progress('REGION', 86, 87)
  387.             self.db.progress('INFO', 'ubiquity/install/keyboard')
  388.             self.configure_keyboard()
  389.             self.db.progress('SET', 87)
  390.             self.db.progress('REGION', 87, 88)
  391.             self.db.progress('INFO', 'ubiquity/install/migrationassistant')
  392.             self.configure_ma()
  393.             self.db.progress('SET', 88)
  394.             self.db.progress('REGION', 88, 89)
  395.             self.remove_unusable_kernels()
  396.             self.db.progress('SET', 89)
  397.             self.db.progress('REGION', 89, 93)
  398.             self.db.progress('INFO', 'ubiquity/install/hardware')
  399.             self.configure_hardware()
  400.             apt_install_direct = open('/var/lib/ubiquity/apt-install-direct', 'w')
  401.             apt_install_direct.close()
  402.             self.db.progress('SET', 93)
  403.             self.db.progress('REGION', 93, 94)
  404.             self.db.progress('INFO', 'ubiquity/install/bootloader')
  405.             self.configure_bootloader()
  406.             self.db.progress('SET', 94)
  407.             self.db.progress('REGION', 94, 95)
  408.             self.db.progress('INFO', 'ubiquity/install/installing')
  409.             self.install_extras()
  410.             self.db.progress('SET', 95)
  411.             self.db.progress('REGION', 95, 99)
  412.             self.db.progress('INFO', 'ubiquity/install/removing')
  413.             self.remove_extras()
  414.             self.remove_broken_cdrom()
  415.             self.copy_dcd()
  416.             self.db.progress('SET', 99)
  417.             self.db.progress('INFO', 'ubiquity/install/log_files')
  418.             self.copy_logs()
  419.             self.db.progress('SET', 100)
  420.         finally:
  421.             self.cleanup()
  422.             
  423.             try:
  424.                 self.db.progress('STOP')
  425.             except (KeyboardInterrupt, SystemExit):
  426.                 raise 
  427.             except:
  428.                 pass
  429.  
  430.  
  431.  
  432.     
  433.     def copy_file(self, sourcepath, targetpath, md5_check):
  434.         sourcefh = None
  435.         targetfh = None
  436.         
  437.         try:
  438.             while None:
  439.                 sourcefh = open(sourcepath, 'rb')
  440.                 targetfh = open(targetpath, 'wb')
  441.                 if md5_check:
  442.                     sourcehash = md5()
  443.                 
  444.                 while None:
  445.                     buf = sourcefh.read(16384)
  446.                     if not buf:
  447.                         break
  448.                     
  449.                     if md5_check:
  450.                         sourcehash.update(buf)
  451.                         continue
  452.                     continue
  453.                     if not md5_check:
  454.                         break
  455.                     
  456.                 targetfh = open(targetpath, 'rb')
  457.                 if md5_check:
  458.                     targethash = md5()
  459.                 
  460.                 while None:
  461.                     buf = targetfh.read(16384)
  462.                     if not buf:
  463.                         break
  464.                     
  465.                     continue
  466.                     if targethash.digest() != sourcehash.digest():
  467.                         if targetfh:
  468.                             targetfh.close()
  469.                         
  470.                         if sourcefh:
  471.                             sourcefh.close()
  472.                         
  473.                         error_template = 'ubiquity/install/copying_error/md5'
  474.                         self.db.subst(error_template, 'FILE', targetpath)
  475.                         self.db.input('critical', error_template)
  476.                         self.db.go()
  477.                         response = self.db.get(error_template)
  478.                         if response == 'skip':
  479.                             break
  480.                         elif response == 'abort':
  481.                             syslog.syslog(syslog.LOG_ERR, 'MD5 failure on %s' % targetpath)
  482.                             sys.exit(3)
  483.                         elif response == 'retry':
  484.                             pass
  485.                         
  486.                 response == 'skip'
  487.                 break
  488.             if targetfh:
  489.                 targetfh.close()
  490.             
  491.             if sourcefh:
  492.                 sourcefh.close()
  493.             
  494.             return None
  495.  
  496.  
  497.     
  498.     def find_cd_kernel(self):
  499.         '''Find the boot kernel on the CD, if possible.'''
  500.         release_bits = os.uname()[2].split('-')
  501.         if len(release_bits) >= 3:
  502.             subarch = release_bits[2]
  503.         else:
  504.             subarch = None
  505.         for prefix in ('vmlinux', 'vmlinuz'):
  506.             kernel = os.path.join('/cdrom/casper', prefix)
  507.             if os.path.exists(kernel):
  508.                 return kernel
  509.             if subarch:
  510.                 kernel = os.path.join('/cdrom/casper', subarch, prefix)
  511.                 if os.path.exists(kernel):
  512.                     return kernel
  513.                 kernel = os.path.join('/cdrom/casper', '%s-%s' % (prefix, subarch))
  514.                 if os.path.exists(kernel):
  515.                     return kernel
  516.                 continue
  517.             os.path.exists(kernel)
  518.         
  519.  
  520.     
  521.     def archdetect(self):
  522.         archdetect = subprocess.Popen([
  523.             'archdetect'], stdout = subprocess.PIPE)
  524.         answer = archdetect.communicate()[0].strip()
  525.         
  526.         try:
  527.             return answer.split('/', 1)
  528.         except ValueError:
  529.             return (answer, '')
  530.  
  531.  
  532.     
  533.     def generate_blacklist(self):
  534.         if os.path.exists('/cdrom/casper/filesystem.manifest-desktop') and os.path.exists('/cdrom/casper/filesystem.manifest'):
  535.             desktop_packages = set()
  536.             manifest = open('/cdrom/casper/filesystem.manifest-desktop')
  537.             for line in manifest:
  538.                 if line.strip() != '' and not line.startswith('#'):
  539.                     desktop_packages.add(line.split()[0])
  540.                     continue
  541.             
  542.             manifest.close()
  543.             live_packages = set()
  544.             manifest = open('/cdrom/casper/filesystem.manifest')
  545.             for line in manifest:
  546.                 if line.strip() != '' and not line.startswith('#'):
  547.                     live_packages.add(line.split()[0])
  548.                     continue
  549.             
  550.             manifest.close()
  551.             difference = live_packages - desktop_packages
  552.         else:
  553.             difference = set()
  554.         cache = Cache()
  555.         use_restricted = True
  556.         
  557.         try:
  558.             if self.db.get('apt-setup/restricted') == 'false':
  559.                 use_restricted = False
  560.         except debconf.DebconfError:
  561.             pass
  562.  
  563.         if not use_restricted:
  564.             for pkg in cache.keys():
  565.                 if cache[pkg].isInstalled and cache[pkg].section.startswith('restricted/'):
  566.                     difference.add(pkg)
  567.                     continue
  568.             
  569.         
  570.         keep = self.query_recorded_installed()
  571.         (arch, subarch) = self.archdetect()
  572.         if arch in ('amd64', 'i386', 'lpia'):
  573.             keep.add('grub')
  574.             keep.add('grub-pc')
  575.         elif arch == 'armel' and subarch in ('imx51', 'iop32x', 'ixp4xx', 'orion5x'):
  576.             keep.add('flash-kernel')
  577.         elif arch == 'powerpc' and subarch != 'ps3':
  578.             keep.add('yaboot')
  579.             keep.add('hfsutils')
  580.         
  581.         difference -= self.expand_dependencies_simple(cache, keep, difference)
  582.         if len(difference) == 0:
  583.             del cache
  584.             self.blacklist = { }
  585.             return None
  586.         confirmed_remove = set()
  587.         for pkg in sorted(difference):
  588.             if pkg in confirmed_remove:
  589.                 continue
  590.             
  591.             would_remove = self.get_remove_list(cache, [
  592.                 pkg], recursive = True)
  593.             if would_remove <= difference:
  594.                 confirmed_remove |= would_remove
  595.                 continue
  596.             for removedpkg in would_remove:
  597.                 cachedpkg = self.get_cache_pkg(cache, removedpkg)
  598.                 cachedpkg.markKeep()
  599.             
  600.         
  601.         difference = confirmed_remove
  602.         difference = set(filter((lambda x: not os.path.exists('/var/lib/dpkg/info/%s.prerm' % x)), difference))
  603.         cmd = [
  604.             'dpkg',
  605.             '-L']
  606.         cmd.extend(difference)
  607.         subp = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  608.         res = subp.communicate()[0].splitlines()
  609.         u = { }
  610.         for x in res:
  611.             u[x] = 1
  612.         
  613.         self.blacklist = u
  614.  
  615.     
  616.     def copy_all(self):
  617.         '''Core copy process. This is the most important step of this
  618.         stage. It clones live filesystem into a local partition in the
  619.         selected hard disk.'''
  620.         files = []
  621.         total_size = 0
  622.         self.db.progress('START', 0, 100, 'ubiquity/install/title')
  623.         self.db.progress('INFO', 'ubiquity/install/scanning')
  624.         walklen = 0
  625.         for entry in os.walk(self.source):
  626.             walklen += 1
  627.         
  628.         walkpos = 0
  629.         walkprogress = 0
  630.         for dirpath, dirnames, filenames in os.walk(self.source):
  631.             walkpos += 1
  632.             if int((float(walkpos) / walklen) * 10) != walkprogress:
  633.                 walkprogress = int((float(walkpos) / walklen) * 10)
  634.                 self.db.progress('SET', walkprogress)
  635.             
  636.             sourcepath = dirpath[len(self.source) + 1:]
  637.             for name in dirnames + filenames:
  638.                 relpath = os.path.join(sourcepath, name)
  639.                 fqpath = os.path.join(dirpath, name)
  640.                 if relpath != 'etc/fstab':
  641.                     total_size += os.lstat(fqpath).st_size
  642.                     files.append(relpath)
  643.                     continue
  644.             
  645.         
  646.         self.db.progress('SET', 10)
  647.         self.db.progress('INFO', 'ubiquity/install/copying')
  648.         copy_progress = 0
  649.         (copied_size, counter) = (0, 0)
  650.         directory_times = []
  651.         time_start = time.time()
  652.         times = [
  653.             (time_start, copied_size)]
  654.         long_enough = False
  655.         time_last_update = time_start
  656.         if self.db.get('ubiquity/install/md5_check') == 'false':
  657.             md5_check = False
  658.         else:
  659.             md5_check = True
  660.         old_umask = os.umask(0)
  661.         for path in files:
  662.             sourcepath = os.path.join(self.source, path)
  663.             targetpath = os.path.join(self.target, path)
  664.             st = os.lstat(sourcepath)
  665.             mode = stat.S_IMODE(st.st_mode)
  666.             if stat.S_ISLNK(st.st_mode):
  667.                 if os.path.lexists(targetpath):
  668.                     os.unlink(targetpath)
  669.                 
  670.                 linkto = os.readlink(sourcepath)
  671.                 os.symlink(linkto, targetpath)
  672.             elif stat.S_ISDIR(st.st_mode):
  673.                 if not os.path.isdir(targetpath):
  674.                     os.mkdir(targetpath, mode)
  675.                 
  676.             elif stat.S_ISCHR(st.st_mode):
  677.                 os.mknod(targetpath, stat.S_IFCHR | mode, st.st_rdev)
  678.             elif stat.S_ISBLK(st.st_mode):
  679.                 os.mknod(targetpath, stat.S_IFBLK | mode, st.st_rdev)
  680.             elif stat.S_ISFIFO(st.st_mode):
  681.                 os.mknod(targetpath, stat.S_IFIFO | mode)
  682.             elif stat.S_ISSOCK(st.st_mode):
  683.                 os.mknod(targetpath, stat.S_IFSOCK | mode)
  684.             elif stat.S_ISREG(st.st_mode):
  685.                 if '/%s' % path in self.blacklist:
  686.                     syslog.syslog('Not copying %s' % path)
  687.                     continue
  688.                 
  689.                 if os.path.exists(targetpath):
  690.                     os.unlink(targetpath)
  691.                 
  692.                 self.copy_file(sourcepath, targetpath, md5_check)
  693.             
  694.             copied_size += st.st_size
  695.             os.lchown(targetpath, st.st_uid, st.st_gid)
  696.             if not stat.S_ISLNK(st.st_mode):
  697.                 os.chmod(targetpath, mode)
  698.             
  699.             if stat.S_ISDIR(st.st_mode):
  700.                 directory_times.append((targetpath, st.st_atime, st.st_mtime))
  701.             elif not stat.S_ISLNK(st.st_mode):
  702.                 os.utime(targetpath, (st.st_atime, st.st_mtime))
  703.             
  704.             if int(copied_size * 90 / total_size) != copy_progress:
  705.                 copy_progress = int(copied_size * 90 / total_size)
  706.                 self.db.progress('SET', 10 + copy_progress)
  707.             
  708.             time_now = time.time()
  709.             if time_now - times[-1][0] >= 0.5:
  710.                 times.append((time_now, copied_size))
  711.                 if not long_enough and time_now - times[0][0] >= 10:
  712.                     long_enough = True
  713.                 
  714.                 if long_enough and time_now - time_last_update >= 2:
  715.                     time_last_update = time_now
  716.                     while time_now - times[0][0] > 60 and time_now - times[1][0] >= 60:
  717.                         times.pop(0)
  718.                     speed = (times[-1][1] - times[0][1]) / (times[-1][0] - times[0][0])
  719.                     if speed != 0:
  720.                         time_remaining = int((total_size - copied_size) / speed)
  721.                         if time_remaining < 60:
  722.                             self.db.progress('INFO', 'ubiquity/install/copying_minute')
  723.                         
  724.                     
  725.                 
  726.             time_now - time_last_update >= 2
  727.         
  728.         for dirtime in directory_times:
  729.             (directory, atime, mtime) = dirtime
  730.             
  731.             try:
  732.                 os.utime(directory, (atime, mtime))
  733.             continue
  734.             except OSError:
  735.                 continue
  736.             
  737.  
  738.         
  739.         bootdir = os.path.join(self.target, 'boot')
  740.         kernel = self.find_cd_kernel()
  741.         os.umask(old_umask)
  742.         self.db.progress('SET', 100)
  743.         self.db.progress('STOP')
  744.  
  745.     
  746.     def copy_dcd(self):
  747.         '''Copy the Distribution Channel Descriptor (DCD) file into the
  748.         installed system.'''
  749.         dcd = '/cdrom/.disk/ubuntu_dist_channel'
  750.         if os.path.exists(dcd):
  751.             shutil.copy(dcd, os.path.join(self.target, 'var/lib/ubuntu_dist_channel'))
  752.         
  753.  
  754.     
  755.     def copy_logs(self):
  756.         '''copy log files into installed system.'''
  757.         target_dir = os.path.join(self.target, 'var/log/installer')
  758.         if not os.path.exists(target_dir):
  759.             os.makedirs(target_dir)
  760.         
  761.         for log_file in ('/var/log/syslog', '/var/log/partman', '/var/log/installer/version', '/var/log/casper.log'):
  762.             target_log_file = os.path.join(target_dir, os.path.basename(log_file))
  763.             if os.path.isfile(log_file):
  764.                 if not misc.execute('cp', '-a', log_file, target_log_file):
  765.                     syslog.syslog(syslog.LOG_ERR, 'Failed to copy installation log file')
  766.                 
  767.                 os.chmod(target_log_file, stat.S_IRUSR | stat.S_IWUSR)
  768.                 continue
  769.         
  770.         
  771.         try:
  772.             status = open(os.path.join(self.target, 'var/lib/dpkg/status'))
  773.             status_gz = gzip.open(os.path.join(target_dir, 'initial-status.gz'), 'w')
  774.             while True:
  775.                 data = status.read(65536)
  776.                 if not data:
  777.                     break
  778.                 
  779.                 status_gz.write(data)
  780.             status_gz.close()
  781.             status.close()
  782.         except IOError:
  783.             pass
  784.  
  785.         
  786.         try:
  787.             if self.db.get('oem-config/enable') == 'true':
  788.                 oem_id = self.db.get('oem-config/id')
  789.                 oem_id_file = open(os.path.join(self.target, 'var/log/installer/oem-id'), 'w')
  790.                 print >>oem_id_file, oem_id
  791.                 oem_id_file.close()
  792.         except (debconf.DebconfError, IOError):
  793.             pass
  794.  
  795.  
  796.     
  797.     def mount_one_image(self, fsfile, mountpoint = None):
  798.         if os.path.splitext(fsfile)[1] == '.cloop':
  799.             blockdev_prefix = 'cloop'
  800.         elif os.path.splitext(fsfile)[1] == '.squashfs':
  801.             blockdev_prefix = 'loop'
  802.         
  803.         if blockdev_prefix == '':
  804.             raise InstallStepError('No source device found for %s' % fsfile)
  805.         blockdev_prefix == ''
  806.         dev = ''
  807.         sysloops = (filter,)((lambda x: x.startswith(blockdev_prefix)), os.listdir('/sys/block'))
  808.         sysloops.sort()
  809.         for sysloop in sysloops:
  810.             
  811.             try:
  812.                 sysloopf = open(os.path.join('/sys/block', sysloop, 'size'))
  813.                 sysloopsize = sysloopf.readline().strip()
  814.                 sysloopf.close()
  815.                 if sysloopsize == '0':
  816.                     devnull = open('/dev/null')
  817.                     if osextras.find_on_path('udevadm'):
  818.                         udevinfo_cmd = [
  819.                             'udevadm',
  820.                             'info']
  821.                     else:
  822.                         udevinfo_cmd = [
  823.                             'udevinfo']
  824.                     udevinfo_cmd.extend([
  825.                         '-q',
  826.                         'name',
  827.                         '-p',
  828.                         os.path.join('/block', sysloop)])
  829.                     udevinfo = subprocess.Popen(udevinfo_cmd, stdout = subprocess.PIPE, stderr = devnull)
  830.                     devbase = udevinfo.communicate()[0]
  831.                     devnull.close()
  832.                     if udevinfo.returncode != 0:
  833.                         devbase = sysloop
  834.                     
  835.                     dev = '/dev/%s' % devbase
  836.                     break
  837.             continue
  838.             continue
  839.             continue
  840.  
  841.         
  842.         if dev == '':
  843.             raise InstallStepError('No loop device available for %s' % fsfile)
  844.         dev == ''
  845.         misc.execute('losetup', dev, fsfile)
  846.         if mountpoint is None:
  847.             mountpoint = '/var/lib/ubiquity/%s' % sysloop
  848.         
  849.         if not os.path.isdir(mountpoint):
  850.             os.mkdir(mountpoint)
  851.         
  852.         if not misc.execute('mount', dev, mountpoint):
  853.             misc.execute('losetup', '-d', dev)
  854.             misc.execute('mount', '-o', 'loop', fsfile, mountpoint)
  855.             dev = 'unused'
  856.         
  857.         return (dev, mountpoint)
  858.  
  859.     
  860.     def mount_source(self):
  861.         '''mounting loop system from cloop or squashfs system.'''
  862.         self.devs = []
  863.         self.mountpoints = []
  864.         if not os.path.isdir(self.source):
  865.             syslog.syslog('mkdir %s' % self.source)
  866.             os.mkdir(self.source)
  867.         
  868.         fs_preseed = self.db.get('ubiquity/install/filesystem-images')
  869.         if fs_preseed == '':
  870.             mounts = open('/proc/mounts')
  871.             for line in mounts:
  872.                 (device, fstype) = line.split()[1:3]
  873.                 if fstype == 'squashfs' and os.path.exists(device):
  874.                     misc.execute('mount', '--bind', device, self.source)
  875.                     self.mountpoints.append(self.source)
  876.                     mounts.close()
  877.                     return None
  878.             
  879.             mounts.close()
  880.             fsfiles = [
  881.                 '/cdrom/casper/filesystem.cloop',
  882.                 '/cdrom/casper/filesystem.squashfs',
  883.                 '/cdrom/META/META.squashfs',
  884.                 '/live/image/live/filesystem.squashfs']
  885.             for fsfile in fsfiles:
  886.                 if fsfile != '' and os.path.isfile(fsfile):
  887.                     (dev, mountpoint) = self.mount_one_image(fsfile, self.source)
  888.                     self.devs.append(dev)
  889.                     self.mountpoints.append(mountpoint)
  890.                     continue
  891.                 os.path.exists(device)
  892.             
  893.         elif len(fs_preseed.split()) == 1:
  894.             if not os.path.isfile(fs_preseed):
  895.                 raise InstallStepError('Preseeded filesystem image %s not found' % fs_preseed)
  896.             (dev, mountpoint) = os.path.isfile(fs_preseed).mount_one_image(fsfile, self.source)
  897.             self.devs.append(dev)
  898.             self.mountpoints.append(mountpoint)
  899.         
  900.         fs_preseed == ''
  901.         for fsfile in fs_preseed.split():
  902.             if not os.path.isfile(fsfile):
  903.                 raise InstallStepError('Preseeded filesystem image %s not found' % fsfile)
  904.             os.path.isfile(fsfile)
  905.             (dev, mountpoint) = self.mount_one_image(fsfile)
  906.             self.devs.append(dev)
  907.             self.mountpoints.append(mountpoint)
  908.         
  909.         if not self.devs:
  910.             raise AssertionError
  911.         if not self.mountpoints:
  912.             raise AssertionError
  913.         misc.execute('mount', '-t', 'unionfs', '-o', 'dirs=' + ':'.join(map((lambda x: '%s=ro' % x), self.mountpoints)), 'unionfs', self.source)
  914.         self.mountpoints.append(self.source)
  915.  
  916.     
  917.     def umount_source(self):
  918.         '''umounting loop system from cloop or squashfs system.'''
  919.         devs = self.devs
  920.         devs.reverse()
  921.         mountpoints = self.mountpoints
  922.         mountpoints.reverse()
  923.         for mountpoint in mountpoints:
  924.             if not misc.execute('umount', mountpoint):
  925.                 raise InstallStepError('Failed to unmount %s' % mountpoint)
  926.             misc.execute('umount', mountpoint)
  927.         
  928.         for dev in devs:
  929.             if dev != '' and dev != 'unused' and not misc.execute('losetup', '-d', dev):
  930.                 raise InstallStepError('Failed to detach loopback device %s' % dev)
  931.             not misc.execute('losetup', '-d', dev)
  932.         
  933.  
  934.     
  935.     def chroot_setup(self, x11 = False):
  936.         '''Set up /target for safe package management operations.'''
  937.         policy_rc_d = os.path.join(self.target, 'usr/sbin/policy-rc.d')
  938.         f = open(policy_rc_d, 'w')
  939.         print >>f, '#!/bin/sh\nexit 101'
  940.         f.close()
  941.         os.chmod(policy_rc_d, 493)
  942.         start_stop_daemon = os.path.join(self.target, 'sbin/start-stop-daemon')
  943.         if os.path.exists(start_stop_daemon):
  944.             os.rename(start_stop_daemon, '%s.REAL' % start_stop_daemon)
  945.         
  946.         f = open(start_stop_daemon, 'w')
  947.         print >>f, "#!/bin/sh\necho 1>&2\necho 'Warning: Fake start-stop-daemon called, doing nothing.' 1>&2\nexit 0"
  948.         f.close()
  949.         os.chmod(start_stop_daemon, 493)
  950.         if not os.path.exists(os.path.join(self.target, 'proc/cmdline')):
  951.             self.chrex('mount', '-t', 'proc', 'proc', '/proc')
  952.         
  953.         if not os.path.exists(os.path.join(self.target, 'sys/devices')):
  954.             self.chrex('mount', '-t', 'sysfs', 'sysfs', '/sys')
  955.         
  956.         if x11 and 'DISPLAY' in os.environ:
  957.             if 'SUDO_USER' in os.environ:
  958.                 xauthority = os.path.expanduser('~%s/.Xauthority' % os.environ['SUDO_USER'])
  959.             else:
  960.                 xauthority = os.path.expanduser('~/.Xauthority')
  961.             if os.path.exists(xauthority):
  962.                 shutil.copy(xauthority, os.path.join(self.target, 'root/.Xauthority'))
  963.             
  964.             if not os.path.isdir(os.path.join(self.target, 'tmp/.X11-unix')):
  965.                 os.mkdir(os.path.join(self.target, 'tmp/.X11-unix'))
  966.             
  967.             misc.execute('mount', '--bind', '/tmp/.X11-unix', os.path.join(self.target, 'tmp/.X11-unix'))
  968.         
  969.  
  970.     
  971.     def chroot_cleanup(self, x11 = False):
  972.         '''Undo the work done by chroot_setup.'''
  973.         if x11 and 'DISPLAY' in os.environ:
  974.             misc.execute('umount', os.path.join(self.target, 'tmp/.X11-unix'))
  975.             
  976.             try:
  977.                 os.rmdir(os.path.join(self.target, 'tmp/.X11-unix'))
  978.             except OSError:
  979.                 pass
  980.  
  981.             
  982.             try:
  983.                 os.unlink(os.path.join(self.target, 'root/.Xauthority'))
  984.             except OSError:
  985.                 pass
  986.             except:
  987.                 None<EXCEPTION MATCH>OSError
  988.             
  989.  
  990.         None<EXCEPTION MATCH>OSError
  991.         self.chrex('umount', '/sys')
  992.         self.chrex('umount', '/proc')
  993.         start_stop_daemon = os.path.join(self.target, 'sbin/start-stop-daemon')
  994.         os.rename('%s.REAL' % start_stop_daemon, start_stop_daemon)
  995.         policy_rc_d = os.path.join(self.target, 'usr/sbin/policy-rc.d')
  996.         os.unlink(policy_rc_d)
  997.  
  998.     
  999.     def run_target_config_hooks(self):
  1000.         '''Run hook scripts from /usr/lib/ubiquity/target-config. This allows
  1001.         casper to hook into us and repeat bits of its configuration in the
  1002.         target system.'''
  1003.         hookdir = '/usr/lib/ubiquity/target-config'
  1004.         if os.path.isdir(hookdir):
  1005.             hooks = filter((lambda entry: '.' not in entry), os.listdir(hookdir))
  1006.             self.db.progress('START', 0, len(hooks), 'ubiquity/install/title')
  1007.             self.db.progress('INFO', 'ubiquity/install/target_hooks')
  1008.             for hookentry in hooks:
  1009.                 hook = os.path.join(hookdir, hookentry)
  1010.                 if not os.access(hook, os.X_OK):
  1011.                     self.db.progress('STEP', 1)
  1012.                     continue
  1013.                 
  1014.                 subprocess.call([
  1015.                     'log-output',
  1016.                     '-t',
  1017.                     'ubiquity',
  1018.                     '--pass-stdout',
  1019.                     hook])
  1020.                 self.db.progress('STEP', 1)
  1021.             
  1022.             self.db.progress('STOP')
  1023.         
  1024.  
  1025.     
  1026.     def configure_locales(self):
  1027.         '''Apply locale settings to installed system.'''
  1028.         dbfilter = language_apply.LanguageApply(None)
  1029.         ret = dbfilter.run_command(auto_process = True)
  1030.         if ret != 0:
  1031.             raise InstallStepError('LanguageApply failed with code %d' % ret)
  1032.         ret != 0
  1033.         self.chrex('fontconfig-voodoo', '--auto', '--force', '--quiet')
  1034.  
  1035.     
  1036.     def configure_apt(self):
  1037.         '''Configure /etc/apt/sources.list.'''
  1038.         apt_conf_tc = open(os.path.join(self.target, 'etc/apt/apt.conf.d/00trustcdrom'), 'w')
  1039.         print >>apt_conf_tc, 'APT::Authentication::TrustCDROM "true";'
  1040.         apt_conf_tc.close()
  1041.         apt_conf_itc = open(os.path.join(self.target, 'etc/apt/apt.conf.d/00IgnoreTimeConflict'), 'w')
  1042.         print >>apt_conf_itc, 'Acquire::gpgv::Options { "--ignore-time-conflict"; };'
  1043.         apt_conf_itc.close()
  1044.         
  1045.         try:
  1046.             if self.db.get('debian-installer/allow_unauthenticated') == 'true':
  1047.                 apt_conf_au = open(os.path.join(self.target, 'etc/apt/apt.conf.d/00AllowUnauthenticated'), 'w')
  1048.                 print >>apt_conf_au, 'APT::Get::AllowUnauthenticated "true";'
  1049.                 print >>apt_conf_au, 'Aptitude::CmdLine::Ignore-Trust-Violations "true";'
  1050.                 apt_conf_au.close()
  1051.         except debconf.DebconfError:
  1052.             pass
  1053.  
  1054.         target_cdrom = os.path.join(self.target, 'cdrom')
  1055.         misc.execute('umount', target_cdrom)
  1056.         if not os.path.exists(target_cdrom):
  1057.             os.mkdir(target_cdrom)
  1058.         
  1059.         misc.execute('mount', '--bind', '/cdrom', target_cdrom)
  1060.         apt_conf_nmc = open(os.path.join(self.target, 'etc/apt/apt.conf.d/00NoMountCDROM'), 'w')
  1061.         print >>apt_conf_nmc, textwrap.dedent('            APT::CDROM::NoMount "true";\n            Acquire::cdrom {\n              mount "/cdrom";\n              "/cdrom/" {\n                Mount  "true";\n                UMount "true";\n              };\n            }')
  1062.         apt_conf_nmc.close()
  1063.         
  1064.         try:
  1065.             shutil.rmtree(os.path.join(self.target, 'var/lib/apt-xapian-index'), ignore_errors = True)
  1066.         except OSError:
  1067.             pass
  1068.  
  1069.         dbfilter = apt_setup.AptSetup(None, self.db)
  1070.         ret = dbfilter.run_command(auto_process = True)
  1071.         if ret != 0:
  1072.             raise InstallStepError('AptSetup failed with code %d' % ret)
  1073.         ret != 0
  1074.  
  1075.     
  1076.     def get_cache_pkg(self, cache, pkg):
  1077.         
  1078.         try:
  1079.             return cache[pkg]
  1080.         except KeyError:
  1081.             return None
  1082.  
  1083.  
  1084.     
  1085.     def record_installed(self, pkgs):
  1086.         """Record which packages we've explicitly installed so that we don't
  1087.         try to remove them later."""
  1088.         record_file = '/var/lib/ubiquity/apt-installed'
  1089.         if not os.path.exists(os.path.dirname(record_file)):
  1090.             os.makedirs(os.path.dirname(record_file))
  1091.         
  1092.         record = open(record_file, 'a')
  1093.         for pkg in pkgs:
  1094.             print >>record, pkg
  1095.         
  1096.         record.close()
  1097.  
  1098.     
  1099.     def query_recorded_installed(self):
  1100.         apt_installed = set()
  1101.         if os.path.exists('/var/lib/ubiquity/apt-installed'):
  1102.             record_file = open('/var/lib/ubiquity/apt-installed')
  1103.             for line in record_file:
  1104.                 apt_installed.add(line.strip())
  1105.             
  1106.             record_file.close()
  1107.         
  1108.         return apt_installed
  1109.  
  1110.     
  1111.     def mark_install(self, cache, pkg):
  1112.         cachedpkg = self.get_cache_pkg(cache, pkg)
  1113.         if cachedpkg is not None and not (cachedpkg.isInstalled):
  1114.             apt_error = False
  1115.             
  1116.             try:
  1117.                 cachedpkg.markInstall()
  1118.             except SystemError:
  1119.                 apt_error = True
  1120.  
  1121.             if cache._depcache.BrokenCount > 0 or apt_error:
  1122.                 brokenpkgs = self.broken_packages(cache)
  1123.                 while brokenpkgs:
  1124.                     for brokenpkg in brokenpkgs:
  1125.                         self.get_cache_pkg(cache, brokenpkg).markKeep()
  1126.                     
  1127.                     new_brokenpkgs = self.broken_packages(cache)
  1128.                     if brokenpkgs == new_brokenpkgs:
  1129.                         break
  1130.                     
  1131.                     brokenpkgs = new_brokenpkgs
  1132.                 if not cache._depcache.BrokenCount == 0:
  1133.                     raise AssertionError
  1134.             
  1135.         
  1136.  
  1137.     
  1138.     def select_language_packs(self):
  1139.         
  1140.         try:
  1141.             keep_packages = self.db.get('ubiquity/keep-installed')
  1142.             keep_packages = keep_packages.replace(',', '').split()
  1143.             syslog.syslog('keeping packages due to preseeding: %s' % ' '.join(keep_packages))
  1144.             self.record_installed(keep_packages)
  1145.         except debconf.DebconfError:
  1146.             pass
  1147.  
  1148.         langpacks = []
  1149.         
  1150.         try:
  1151.             langpack_db = self.db.get('pkgsel/language-packs')
  1152.             langpacks = langpack_db.replace(',', '').split()
  1153.         except debconf.DebconfError:
  1154.             pass
  1155.  
  1156.         if not langpacks:
  1157.             
  1158.             try:
  1159.                 langpack_db = self.db.get('localechooser/supported-locales')
  1160.                 langpack_set = set()
  1161.                 for locale in langpack_db.replace(',', '').split():
  1162.                     langpack_set.add(locale.split('_')[0])
  1163.                 
  1164.                 langpacks = sorted(langpack_set)
  1165.             except debconf.DebconfError:
  1166.                 pass
  1167.             except:
  1168.                 None<EXCEPTION MATCH>debconf.DebconfError
  1169.             
  1170.  
  1171.         None<EXCEPTION MATCH>debconf.DebconfError
  1172.         if not langpacks:
  1173.             langpack_db = self.db.get('debian-installer/locale')
  1174.             langpacks = [
  1175.                 langpack_db.split('_')[0]]
  1176.         
  1177.         syslog.syslog('keeping language packs for: %s' % ' '.join(langpacks))
  1178.         
  1179.         try:
  1180.             lppatterns = self.db.get('pkgsel/language-pack-patterns').split()
  1181.         except debconf.DebconfError:
  1182.             return None
  1183.  
  1184.         to_install = []
  1185.         for lp in langpacks:
  1186.             to_install.append('language-pack-%s' % lp)
  1187.             for pattern in lppatterns:
  1188.                 to_install.append(pattern.replace('$LL', lp))
  1189.             
  1190.             to_install.append('language-support-%s' % lp)
  1191.         
  1192.         cache = Cache()
  1193.         to_install = _[1]
  1194.         del cache
  1195.         self.record_installed(to_install)
  1196.         self.langpacks = to_install
  1197.  
  1198.     
  1199.     def install_language_packs(self):
  1200.         self.do_install(self.langpacks)
  1201.         cache = Cache()
  1202.         incomplete = False
  1203.         for pkg in self.langpacks:
  1204.             cachedpkg = self.get_cache_pkg(cache, pkg)
  1205.             if cachedpkg is None or not (cachedpkg.isInstalled):
  1206.                 incomplete = True
  1207.                 break
  1208.                 continue
  1209.         
  1210.         if incomplete:
  1211.             language_support_dir = os.path.join(self.target, 'usr/share/language-support')
  1212.             update_notifier_dir = os.path.join(self.target, 'var/lib/update-notifier/user.d')
  1213.             for note in ('incomplete-language-support-gnome.note', 'incomplete-language-support-qt.note'):
  1214.                 notepath = os.path.join(language_support_dir, note)
  1215.                 if os.path.exists(notepath):
  1216.                     if not os.path.exists(update_notifier_dir):
  1217.                         os.makedirs(update_notifier_dir)
  1218.                     
  1219.                     shutil.copy(notepath, os.path.join(update_notifier_dir, note))
  1220.                     break
  1221.                     continue
  1222.             
  1223.         
  1224.  
  1225.     
  1226.     def configure_timezone(self):
  1227.         '''Set timezone on installed system.'''
  1228.         dbfilter = timezone_apply.TimezoneApply(None)
  1229.         ret = dbfilter.run_command(auto_process = True)
  1230.         if ret != 0:
  1231.             raise InstallStepError('TimezoneApply failed with code %d' % ret)
  1232.         ret != 0
  1233.         dbfilter = clock_setup.ClockSetup(None)
  1234.         ret = dbfilter.run_command(auto_process = True)
  1235.         if ret != 0:
  1236.             raise InstallStepError('ClockSetup failed with code %d' % ret)
  1237.         ret != 0
  1238.  
  1239.     
  1240.     def configure_keyboard(self):
  1241.         '''Set keyboard in installed system.'''
  1242.         dbfilter = console_setup_apply.ConsoleSetupApply(None)
  1243.         ret = dbfilter.run_command(auto_process = True)
  1244.         if ret != 0:
  1245.             raise InstallStepError('ConsoleSetupApply failed with code %d' % ret)
  1246.         ret != 0
  1247.  
  1248.     
  1249.     def configure_user(self):
  1250.         '''create the user selected along the installation process
  1251.         into the installed system. Default user from live system is
  1252.         deleted and skel for this new user is copied to $HOME.'''
  1253.         dbfilter = usersetup_apply.UserSetupApply(None)
  1254.         ret = dbfilter.run_command(auto_process = True)
  1255.         if ret != 0:
  1256.             raise InstallStepError('UserSetupApply failed with code %d' % ret)
  1257.         ret != 0
  1258.  
  1259.     
  1260.     def configure_ma(self):
  1261.         '''import documents, settings, and users from previous operating
  1262.         systems.'''
  1263.         if 'UBIQUITY_MIGRATION_ASSISTANT' in os.environ:
  1264.             dbfilter = migrationassistant_apply.MigrationAssistantApply(None)
  1265.             ret = dbfilter.run_command(auto_process = True)
  1266.             if ret != 0:
  1267.                 raise InstallStepError('MigrationAssistantApply failed with code %d' % ret)
  1268.             ret != 0
  1269.         
  1270.  
  1271.     
  1272.     def get_resume_partition(self):
  1273.         biggest_size = 0
  1274.         biggest_partition = None
  1275.         swaps = open('/proc/swaps')
  1276.         for line in swaps:
  1277.             words = line.split()
  1278.             if words[1] != 'partition':
  1279.                 continue
  1280.             
  1281.             if not os.path.exists(words[0]):
  1282.                 continue
  1283.             
  1284.             if words[0].startswith('/dev/ramzswap'):
  1285.                 continue
  1286.             
  1287.             size = int(words[2])
  1288.             if size > biggest_size:
  1289.                 biggest_size = size
  1290.                 biggest_partition = words[0]
  1291.                 continue
  1292.         
  1293.         swaps.close()
  1294.         return biggest_partition
  1295.  
  1296.     
  1297.     def configure_hardware(self):
  1298.         '''reconfiguring several packages which depends on the
  1299.         hardware system in which has been installed on and need some
  1300.         automatic configurations to get work.'''
  1301.         self.chroot_setup()
  1302.         
  1303.         try:
  1304.             dbfilter = hw_detect.HwDetect(None, self.db)
  1305.             ret = dbfilter.run_command(auto_process = True)
  1306.             if ret != 0:
  1307.                 raise InstallStepError('HwDetect failed with code %d' % ret)
  1308.             ret != 0
  1309.         finally:
  1310.             self.chroot_cleanup()
  1311.  
  1312.         self.db.progress('INFO', 'ubiquity/install/hardware')
  1313.         misc.execute('/usr/lib/ubiquity/debian-installer-utils/register-module.post-base-installer')
  1314.         resume = self.get_resume_partition()
  1315.         if resume is not None:
  1316.             resume_uuid = None
  1317.             
  1318.             try:
  1319.                 resume_uuid = subprocess.Popen([
  1320.                     'vol_id',
  1321.                     '-u',
  1322.                     resume], stdout = subprocess.PIPE).communicate()[0].rstrip('\n')
  1323.             except OSError:
  1324.                 pass
  1325.  
  1326.             if resume_uuid:
  1327.                 resume = 'UUID=%s' % resume_uuid
  1328.             
  1329.             if os.path.exists(os.path.join(self.target, 'etc/initramfs-tools/conf.d')):
  1330.                 configdir = os.path.join(self.target, 'etc/initramfs-tools/conf.d')
  1331.             elif os.path.exists(os.path.join(self.target, 'etc/mkinitramfs/conf.d')):
  1332.                 configdir = os.path.join(self.target, 'etc/mkinitramfs/conf.d')
  1333.             else:
  1334.                 configdir = None
  1335.             if configdir is not None:
  1336.                 configfile = open(os.path.join(configdir, 'resume'), 'w')
  1337.                 print >>configfile, 'RESUME=%s' % resume
  1338.                 configfile.close()
  1339.             
  1340.         
  1341.         
  1342.         try:
  1343.             os.unlink('/target/etc/usplash.conf')
  1344.         except OSError:
  1345.             pass
  1346.  
  1347.         
  1348.         try:
  1349.             modes = self.db.get('xserver-xorg/config/display/modes')
  1350.             self.set_debconf('xserver-xorg/config/display/modes', modes)
  1351.         except debconf.DebconfError:
  1352.             pass
  1353.  
  1354.         
  1355.         try:
  1356.             os.unlink('/target/etc/popularity-contest.conf')
  1357.         except OSError:
  1358.             pass
  1359.  
  1360.         
  1361.         try:
  1362.             participate = self.db.get('popularity-contest/participate')
  1363.             self.set_debconf('popularity-contest/participate', participate)
  1364.         except debconf.DebconfError:
  1365.             pass
  1366.  
  1367.         
  1368.         try:
  1369.             os.unlink('/target/etc/papersize')
  1370.         except OSError:
  1371.             pass
  1372.  
  1373.         subprocess.call([
  1374.             'log-output',
  1375.             '-t',
  1376.             'ubiquity',
  1377.             'chroot',
  1378.             self.target,
  1379.             'ucf',
  1380.             '--purge',
  1381.             '/etc/papersize'], preexec_fn = debconf_disconnect, close_fds = True)
  1382.         
  1383.         try:
  1384.             self.set_debconf('libpaper/defaultpaper', '')
  1385.         except debconf.DebconfError:
  1386.             pass
  1387.  
  1388.         
  1389.         try:
  1390.             os.unlink('/target/etc/ssl/certs/ssl-cert-snakeoil.pem')
  1391.         except OSError:
  1392.             pass
  1393.  
  1394.         
  1395.         try:
  1396.             os.unlink('/target/etc/ssl/private/ssl-cert-snakeoil.key')
  1397.         except OSError:
  1398.             pass
  1399.  
  1400.         self.chroot_setup(x11 = True)
  1401.         self.chrex('dpkg-divert', '--package', 'ubiquity', '--rename', '--quiet', '--add', '/usr/sbin/update-initramfs')
  1402.         
  1403.         try:
  1404.             os.symlink('/bin/true', '/target/usr/sbin/update-initramfs')
  1405.         except OSError:
  1406.             pass
  1407.  
  1408.         packages = [
  1409.             'linux-image-' + self.kernel_version,
  1410.             'linux-restricted-modules-' + self.kernel_version,
  1411.             'usplash',
  1412.             'splashy',
  1413.             'popularity-contest',
  1414.             'libpaper1',
  1415.             'ssl-cert']
  1416.         
  1417.         try:
  1418.             for package in packages:
  1419.                 self.reconfigure(package)
  1420.         finally:
  1421.             
  1422.             try:
  1423.                 os.unlink('/target/usr/sbin/update-initramfs')
  1424.             except OSError:
  1425.                 pass
  1426.  
  1427.             self.chrex('dpkg-divert', '--package', 'ubiquity', '--rename', '--quiet', '--remove', '/usr/sbin/update-initramfs')
  1428.             self.chrex('update-initramfs', '-c', '-k', os.uname()[2])
  1429.             self.chroot_cleanup(x11 = True)
  1430.  
  1431.         bootdir = os.path.join(self.target, 'boot')
  1432.         if self.db.get('base-installer/kernel/linux/link_in_boot') == 'true':
  1433.             linkdir = bootdir
  1434.             linkprefix = ''
  1435.         else:
  1436.             linkdir = self.target
  1437.             linkprefix = 'boot'
  1438.         re_symlink = re.compile('vmlinu[xz]|initrd.img$')
  1439.         for entry in os.listdir(linkdir):
  1440.             if re_symlink.match(entry) is not None:
  1441.                 filename = os.path.join(linkdir, entry)
  1442.                 if os.path.islink(filename):
  1443.                     os.unlink(filename)
  1444.                 
  1445.             os.path.islink(filename)
  1446.         
  1447.         if linkdir != self.target:
  1448.             for entry in os.listdir(self.target):
  1449.                 if re_symlink.match(entry) is not None:
  1450.                     filename = os.path.join(self.target, entry)
  1451.                     if os.path.islink(filename):
  1452.                         os.unlink(filename)
  1453.                     
  1454.                 os.path.islink(filename)
  1455.             
  1456.         
  1457.         re_image = re.compile('(vmlinu[xz]|initrd.img)-')
  1458.         for entry in os.listdir(bootdir):
  1459.             match = re_image.match(entry)
  1460.             if match is not None:
  1461.                 imagetype = match.group(1)
  1462.                 linksrc = os.path.join(linkprefix, entry)
  1463.                 linkdst = os.path.join(linkdir, imagetype)
  1464.                 if os.path.exists(linkdst):
  1465.                     if entry.endswith('-' + self.kernel_version):
  1466.                         os.unlink(linkdst)
  1467.                     
  1468.                 
  1469.                 os.symlink(linksrc, linkdst)
  1470.                 continue
  1471.         
  1472.  
  1473.     
  1474.     def get_all_interfaces(self):
  1475.         '''Get all non-local network interfaces.'''
  1476.         ifs = []
  1477.         ifs_file = open('/proc/net/dev')
  1478.         ifs_file.readline()
  1479.         ifs_file.readline()
  1480.         for line in ifs_file:
  1481.             name = re.match('(.*?(?::\\d+)?):', line.strip()).group(1)
  1482.             if name == 'lo':
  1483.                 continue
  1484.             
  1485.             ifs.append(name)
  1486.         
  1487.         ifs_file.close()
  1488.         return ifs
  1489.  
  1490.     
  1491.     def configure_network(self):
  1492.         """Automatically configure the network.
  1493.  
  1494.         At present, the only thing the user gets to tweak in the UI is the
  1495.         hostname. Some other things will be copied from the live filesystem,
  1496.         so changes made there will be reflected in the installed system.
  1497.  
  1498.         Unfortunately, at present we have to duplicate a fair bit of netcfg
  1499.         here, because it's hard to drive netcfg in a way that won't try to
  1500.         bring interfaces up and down."""
  1501.         for path in ('/etc/network/interfaces', '/etc/resolv.conf'):
  1502.             if os.path.exists(path):
  1503.                 shutil.copy2(path, os.path.join(self.target, path[1:]))
  1504.                 continue
  1505.         
  1506.         
  1507.         try:
  1508.             hostname = self.db.get('netcfg/get_hostname')
  1509.         except debconf.DebconfError:
  1510.             hostname = ''
  1511.  
  1512.         
  1513.         try:
  1514.             domain = self.db.get('netcfg/get_domain')
  1515.         except debconf.DebconfError:
  1516.             domain = ''
  1517.  
  1518.         if hostname == '':
  1519.             hostname = 'ubuntu'
  1520.         
  1521.         fp = open(os.path.join(self.target, 'etc/hostname'), 'w')
  1522.         print >>fp, hostname
  1523.         fp.close()
  1524.         hosts = open(os.path.join(self.target, 'etc/hosts'), 'w')
  1525.         print >>hosts, '127.0.0.1\tlocalhost'
  1526.         if domain:
  1527.             print >>hosts, '127.0.1.1\t%s.%s\t%s' % (hostname, domain, hostname)
  1528.         else:
  1529.             print >>hosts, '127.0.1.1\t%s' % hostname
  1530.         print >>hosts, textwrap.dedent('\n            # The following lines are desirable for IPv6 capable hosts\n            ::1     localhost ip6-localhost ip6-loopback\n            fe00::0 ip6-localnet\n            ff00::0 ip6-mcastprefix\n            ff02::1 ip6-allnodes\n            ff02::2 ip6-allrouters\n            ff02::3 ip6-allhosts')
  1531.         hosts.close()
  1532.         persistent_net = '/etc/udev/rules.d/70-persistent-net.rules'
  1533.  
  1534.     
  1535.     def configure_bootloader(self):
  1536.         '''configuring and installing boot loader into installed
  1537.         hardware system.'''
  1538.         install_bootloader = self.db.get('ubiquity/install_bootloader')
  1539.         if install_bootloader == 'true':
  1540.             misc.execute('mount', '--bind', '/proc', self.target + '/proc')
  1541.             misc.execute('mount', '--bind', '/dev', self.target + '/dev')
  1542.             (arch, subarch) = self.archdetect()
  1543.             
  1544.             try:
  1545.                 if arch in ('amd64', 'i386', 'lpia'):
  1546.                     grubinstaller = grubinstaller
  1547.                     import ubiquity.components
  1548.                     dbfilter = grubinstaller.GrubInstaller(None)
  1549.                     ret = dbfilter.run_command(auto_process = True)
  1550.                     if ret != 0:
  1551.                         raise InstallStepError('GrubInstaller failed with code %d' % ret)
  1552.                     ret != 0
  1553.                 elif arch == 'armel' and subarch in ('imx51', 'iop32x', 'ixp4xx', 'orion5x'):
  1554.                     flash_kernel = flash_kernel
  1555.                     import ubiquity.components
  1556.                     dbfilter = flash_kernel.FlashKernel(None)
  1557.                     ret = dbfilter.run_command(auto_process = True)
  1558.                     if ret != 0:
  1559.                         raise InstallStepError('FlashKernel failed with code %d' % ret)
  1560.                     ret != 0
  1561.                 elif arch == 'powerpc' and subarch == 'ps3':
  1562.                     kbootinstaller = kbootinstaller
  1563.                     import ubiquity.components
  1564.                     dbfilter = kbootinstaller.KbootInstaller(None)
  1565.                     ret = dbfilter.run_command(auto_process = True)
  1566.                     if ret != 0:
  1567.                         raise InstallStepError('KbootInstaller failed with code %d' % ret)
  1568.                     ret != 0
  1569.                 elif arch == 'powerpc':
  1570.                     yabootinstaller = yabootinstaller
  1571.                     import ubiquity.components
  1572.                     dbfilter = yabootinstaller.YabootInstaller(None)
  1573.                     ret = dbfilter.run_command(auto_process = True)
  1574.                     if ret != 0:
  1575.                         raise InstallStepError('YabootInstaller failed with code %d' % ret)
  1576.                     ret != 0
  1577.                 else:
  1578.                     raise InstallStepError('No bootloader installer found')
  1579.             except ImportError:
  1580.                 raise InstallStepError('No bootloader installer found')
  1581.             
  1582.  
  1583.             misc.execute('umount', '-f', self.target + '/proc')
  1584.             misc.execute('umount', '-f', self.target + '/dev')
  1585.         
  1586.  
  1587.     
  1588.     def broken_packages(self, cache):
  1589.         expect_count = cache._depcache.BrokenCount
  1590.         count = 0
  1591.         brokenpkgs = set()
  1592.         for pkg in cache.keys():
  1593.             
  1594.             try:
  1595.                 if cache._depcache.IsInstBroken(cache._cache[pkg]):
  1596.                     brokenpkgs.add(pkg)
  1597.                     count += 1
  1598.             except KeyError:
  1599.                 continue
  1600.  
  1601.             if count >= expect_count:
  1602.                 break
  1603.                 continue
  1604.         
  1605.         return brokenpkgs
  1606.  
  1607.     
  1608.     def do_install(self, to_install):
  1609.         if self.langpacks:
  1610.             self.db.progress('START', 0, 10, 'ubiquity/langpacks/title')
  1611.         else:
  1612.             self.db.progress('START', 0, 10, 'ubiquity/install/title')
  1613.         self.db.progress('INFO', 'ubiquity/install/find_installables')
  1614.         self.db.progress('REGION', 0, 1)
  1615.         fetchprogress = DebconfFetchProgress(self.db, 'ubiquity/install/title', 'ubiquity/install/apt_indices_starting', 'ubiquity/install/apt_indices')
  1616.         cache = Cache()
  1617.         if cache._depcache.BrokenCount > 0:
  1618.             syslog.syslog('not installing additional packages, since there are broken packages: %s' % ', '.join(self.broken_packages(cache)))
  1619.             self.db.progress('STOP')
  1620.             return None
  1621.         for pkg in to_install:
  1622.             self.mark_install(cache, pkg)
  1623.         
  1624.         self.db.progress('SET', 1)
  1625.         self.db.progress('REGION', 1, 10)
  1626.         if self.langpacks:
  1627.             fetchprogress = DebconfFetchProgress(self.db, 'ubiquity/langpacks/title', None, 'ubiquity/langpacks/packages')
  1628.             installprogress = DebconfInstallProgress(self.db, 'ubiquity/langpacks/title', 'ubiquity/install/apt_info')
  1629.         else:
  1630.             fetchprogress = DebconfFetchProgress(self.db, 'ubiquity/install/title', None, 'ubiquity/install/fetch_remove')
  1631.             installprogress = DebconfInstallProgress(self.db, 'ubiquity/install/title', 'ubiquity/install/apt_info', 'ubiquity/install/apt_error_install')
  1632.         self.chroot_setup()
  1633.         commit_error = None
  1634.         
  1635.         try:
  1636.             if not cache.commit(fetchprogress, installprogress):
  1637.                 fetchprogress.stop()
  1638.                 installprogress.finishUpdate()
  1639.                 self.db.progress('STOP')
  1640.                 return None
  1641.         except IOError:
  1642.             e = None
  1643.             for line in str(e).split('\n'):
  1644.                 syslog.syslog(syslog.LOG_ERR, line)
  1645.             
  1646.             fetchprogress.stop()
  1647.             installprogress.finishUpdate()
  1648.             self.db.progress('STOP')
  1649.             return None
  1650.             except SystemError:
  1651.                 e = None
  1652.                 for line in str(e).split('\n'):
  1653.                     syslog.syslog(syslog.LOG_ERR, line)
  1654.                 
  1655.                 commit_error = str(e)
  1656.             except:
  1657.                 None<EXCEPTION MATCH>SystemError
  1658.             self.chroot_cleanup()
  1659.         else:
  1660.             self.db.progress('SET', 10)
  1661.             cache.open(None)
  1662.             if commit_error or cache._depcache.BrokenCount > 0:
  1663.                 brokenpkgs = self.broken_packages(cache)
  1664.                 syslog.syslog('broken packages after installation: %s' % ', '.join(brokenpkgs))
  1665.                 self.db.subst('ubiquity/install/broken_install', 'ERROR', commit_error)
  1666.                 self.db.subst('ubiquity/install/broken_install', 'PACKAGES', ', '.join(brokenpkgs))
  1667.                 self.db.input('critical', 'ubiquity/install/broken_install')
  1668.                 self.db.go()
  1669.             
  1670.  
  1671.         self.db.progress('STOP')
  1672.  
  1673.     
  1674.     def expand_dependencies_simple(self, cache, keep, to_remove, recommends = True):
  1675.         '''Return the list of packages in to_remove that clearly cannot be
  1676.         removed if we want to keep the set of packages in keep. Except in
  1677.         the case of Recommends, this is not required for correctness (we
  1678.         could just let apt figure it out), but it allows us to ask apt fewer
  1679.         separate questions, and so is faster.'''
  1680.         keys = [
  1681.             'Pre-Depends',
  1682.             'Depends']
  1683.         if recommends:
  1684.             keys.append('Recommends')
  1685.         
  1686.         to_scan = set(keep)
  1687.         to_scan_next = set()
  1688.         expanded = set(keep)
  1689.         while to_scan:
  1690.             for pkg in to_scan:
  1691.                 cachedpkg = self.get_cache_pkg(cache, pkg)
  1692.                 if cachedpkg is None:
  1693.                     continue
  1694.                 
  1695.                 ver = cachedpkg._pkg.CurrentVer
  1696.                 if ver is None:
  1697.                     continue
  1698.                 
  1699.                 for key in keys:
  1700.                     if key in ver.DependsList:
  1701.                         for dep_or in ver.DependsList[key]:
  1702.                             for dep in dep_or:
  1703.                                 depname = dep.TargetPkg.Name
  1704.                                 cacheddep = self.get_cache_pkg(cache, depname)
  1705.                                 if cacheddep is None:
  1706.                                     continue
  1707.                                 
  1708.                                 if cacheddep._pkg.CurrentVer is not None:
  1709.                                     break
  1710.                                     continue
  1711.                             
  1712.                             if depname in expanded or depname not in to_remove:
  1713.                                 continue
  1714.                             
  1715.                             expanded.add(depname)
  1716.                             to_scan_next.add(depname)
  1717.                         
  1718.                 
  1719.             
  1720.             to_scan = to_scan_next
  1721.             to_scan_next = set()
  1722.         return expanded
  1723.  
  1724.     
  1725.     def get_remove_list(self, cache, to_remove, recursive = False):
  1726.         to_remove = set(to_remove)
  1727.         all_removed = set()
  1728.         while True:
  1729.             removed = set()
  1730.             for pkg in to_remove:
  1731.                 cachedpkg = self.get_cache_pkg(cache, pkg)
  1732.                 if cachedpkg is not None and cachedpkg.isInstalled:
  1733.                     apt_error = False
  1734.                     
  1735.                     try:
  1736.                         cachedpkg.markDelete(autoFix = False, purge = True)
  1737.                     except SystemError:
  1738.                         apt_error = True
  1739.  
  1740.                     if apt_error:
  1741.                         cachedpkg.markKeep()
  1742.                     elif cache._depcache.BrokenCount > 0:
  1743.                         brokenpkgs = self.broken_packages(cache)
  1744.                         broken_removed = set()
  1745.                         while brokenpkgs:
  1746.                             if recursive or brokenpkgs <= to_remove:
  1747.                                 broken_removed_inner = set()
  1748.                                 for pkg2 in brokenpkgs:
  1749.                                     cachedpkg2 = self.get_cache_pkg(cache, pkg2)
  1750.                                     if cachedpkg2 is not None:
  1751.                                         broken_removed_inner.add(pkg2)
  1752.                                         
  1753.                                         try:
  1754.                                             cachedpkg2.markDelete(autoFix = False, purge = True)
  1755.                                         except SystemError:
  1756.                                             apt_error = True
  1757.                                             break
  1758.                                         except:
  1759.                                             None<EXCEPTION MATCH>SystemError
  1760.                                         
  1761.  
  1762.                                     None<EXCEPTION MATCH>SystemError
  1763.                                 
  1764.                                 broken_removed |= broken_removed_inner
  1765.                                 if apt_error or not broken_removed_inner:
  1766.                                     break
  1767.                                 
  1768.                                 brokenpkgs = self.broken_packages(cache)
  1769.                                 continue
  1770.                     if apt_error or cache._depcache.BrokenCount > 0:
  1771.                         for pkg2 in broken_removed:
  1772.                             self.get_cache_pkg(cache, pkg2).markKeep()
  1773.                         
  1774.                         cachedpkg.markKeep()
  1775.                     else:
  1776.                         removed.add(pkg)
  1777.                         removed |= broken_removed
  1778.                 else:
  1779.                     removed.add(pkg)
  1780.                 if not cache._depcache.BrokenCount == 0:
  1781.                     raise AssertionError
  1782.                 cache._depcache.BrokenCount == 0
  1783.             
  1784.             if not removed:
  1785.                 break
  1786.             
  1787.             to_remove -= removed
  1788.             all_removed |= removed
  1789.         return all_removed
  1790.  
  1791.     
  1792.     def do_remove(self, to_remove, recursive = False):
  1793.         self.db.progress('START', 0, 5, 'ubiquity/install/title')
  1794.         self.db.progress('INFO', 'ubiquity/install/find_removables')
  1795.         fetchprogress = DebconfFetchProgress(self.db, 'ubiquity/install/title', 'ubiquity/install/apt_indices_starting', 'ubiquity/install/apt_indices')
  1796.         cache = Cache()
  1797.         if cache._depcache.BrokenCount > 0:
  1798.             syslog.syslog('not processing removals, since there are broken packages: %s' % ', '.join(self.broken_packages(cache)))
  1799.             self.db.progress('STOP')
  1800.             return None
  1801.         self.get_remove_list(cache, to_remove, recursive)
  1802.         self.db.progress('SET', 1)
  1803.         self.db.progress('REGION', 1, 5)
  1804.         fetchprogress = DebconfFetchProgress(self.db, 'ubiquity/install/title', None, 'ubiquity/install/fetch_remove')
  1805.         installprogress = DebconfInstallProgress(self.db, 'ubiquity/install/title', 'ubiquity/install/apt_info', 'ubiquity/install/apt_error_remove')
  1806.         self.chroot_setup()
  1807.         commit_error = None
  1808.         
  1809.         try:
  1810.             if not cache.commit(fetchprogress, installprogress):
  1811.                 fetchprogress.stop()
  1812.                 installprogress.finishUpdate()
  1813.                 self.db.progress('STOP')
  1814.                 return None
  1815.         except SystemError:
  1816.             cache._depcache.BrokenCount > 0
  1817.             e = cache._depcache.BrokenCount > 0
  1818.             for line in str(e).split('\n'):
  1819.                 syslog.syslog(syslog.LOG_ERR, line)
  1820.             
  1821.             commit_error = str(e)
  1822.         except:
  1823.             cache._depcache.BrokenCount > 0
  1824.         finally:
  1825.             self.chroot_cleanup()
  1826.  
  1827.         self.db.progress('SET', 5)
  1828.         cache.open(None)
  1829.         self.db.progress('STOP')
  1830.  
  1831.     
  1832.     def remove_unusable_kernels(self):
  1833.         '''Remove unusable kernels; keeping them may cause us to be unable
  1834.         to boot.'''
  1835.         self.db.progress('START', 0, 5, 'ubiquity/install/title')
  1836.         self.db.progress('INFO', 'ubiquity/install/find_removables')
  1837.         dbfilter = check_kernels.CheckKernels(None)
  1838.         dbfilter.run_command(auto_process = True)
  1839.         remove_kernels = set()
  1840.         if os.path.exists('/var/lib/ubiquity/remove-kernels'):
  1841.             remove_kernels_file = open('/var/lib/ubiquity/remove-kernels')
  1842.             for line in remove_kernels_file:
  1843.                 remove_kernels.add(line.strip())
  1844.             
  1845.             remove_kernels_file.close()
  1846.         
  1847.         if len(remove_kernels) == 0:
  1848.             self.db.progress('STOP')
  1849.             return None
  1850.         self.db.progress('SET', 1)
  1851.         self.db.progress('REGION', 1, 5)
  1852.         
  1853.         try:
  1854.             self.do_remove(remove_kernels, recursive = True)
  1855.         except:
  1856.             len(remove_kernels) == 0
  1857.             self.db.progress('STOP')
  1858.             raise 
  1859.  
  1860.         self.db.progress('SET', 5)
  1861.         self.db.progress('STOP')
  1862.  
  1863.     
  1864.     def install_extras(self):
  1865.         '''Try to install additional packages requested by installer
  1866.         components.'''
  1867.         sources_list = os.path.join(self.target, 'etc/apt/sources.list')
  1868.         os.rename(sources_list, '%s.apt-setup' % sources_list)
  1869.         old_sources = open('%s.apt-setup' % sources_list)
  1870.         new_sources = open(sources_list, 'w')
  1871.         found_cdrom = False
  1872.         for line in old_sources:
  1873.             if 'cdrom:' in line:
  1874.                 print >>new_sources, line,
  1875.                 found_cdrom = True
  1876.                 continue
  1877.         
  1878.         new_sources.close()
  1879.         old_sources.close()
  1880.         if not found_cdrom:
  1881.             os.rename('%s.apt-setup' % sources_list, sources_list)
  1882.         
  1883.         self.do_install(self.query_recorded_installed())
  1884.         if found_cdrom:
  1885.             os.rename('%s.apt-setup' % sources_list, sources_list)
  1886.         
  1887.         
  1888.         try:
  1889.             if self.db.get('oem-config/enable') == 'true':
  1890.                 if os.path.isdir(os.path.join(self.target, 'home/oem')):
  1891.                     open(os.path.join(self.target, 'home/oem/.hwdb'), 'w').close()
  1892.                     for desktop_file in ('usr/share/applications/oem-config-prepare-gtk.desktop', 'usr/share/applications/kde/oem-config-prepare-kde.desktop'):
  1893.                         if os.path.exists(os.path.join(self.target, desktop_file)):
  1894.                             desktop_base = os.path.basename(desktop_file)
  1895.                             self.chrex('install', '-d', '-o', 'oem', '-g', 'oem', '/home/oem/Desktop')
  1896.                             self.chrex('install', '-o', 'oem', '-g', 'oem', '/%s' % desktop_file, '/home/oem/Desktop/%s' % desktop_base)
  1897.                             break
  1898.                             continue
  1899.                     
  1900.                 
  1901.                 di_locale = self.db.get('debian-installer/locale')
  1902.                 if di_locale:
  1903.                     self.set_debconf('debian-installer/locale', di_locale)
  1904.                 
  1905.         except debconf.DebconfError:
  1906.             pass
  1907.  
  1908.  
  1909.     
  1910.     def remove_extras(self):
  1911.         '''Try to remove packages that are needed on the live CD but not on
  1912.         the installed system.'''
  1913.         if os.path.exists('/cdrom/casper/filesystem.manifest-desktop') and os.path.exists('/cdrom/casper/filesystem.manifest'):
  1914.             desktop_packages = set()
  1915.             manifest = open('/cdrom/casper/filesystem.manifest-desktop')
  1916.             for line in manifest:
  1917.                 if line.strip() != '' and not line.startswith('#'):
  1918.                     desktop_packages.add(line.split()[0])
  1919.                     continue
  1920.             
  1921.             manifest.close()
  1922.             live_packages = set()
  1923.             manifest = open('/cdrom/casper/filesystem.manifest')
  1924.             for line in manifest:
  1925.                 if line.strip() != '' and not line.startswith('#'):
  1926.                     live_packages.add(line.split()[0])
  1927.                     continue
  1928.             
  1929.             manifest.close()
  1930.             difference = live_packages - desktop_packages
  1931.         else:
  1932.             difference = set()
  1933.         keep = self.query_recorded_installed()
  1934.         (arch, subarch) = self.archdetect()
  1935.         if arch in ('amd64', 'i386', 'lpia'):
  1936.             if 'grub' not in keep:
  1937.                 difference.add('grub')
  1938.             
  1939.             if 'grub-pc' not in keep:
  1940.                 difference.add('grub-pc')
  1941.             
  1942.             if 'lilo' not in keep:
  1943.                 difference.add('lilo')
  1944.             
  1945.         
  1946.         cache = Cache()
  1947.         difference -= self.expand_dependencies_simple(cache, keep, difference)
  1948.         del cache
  1949.         if len(difference) == 0:
  1950.             return None
  1951.         use_restricted = True
  1952.         
  1953.         try:
  1954.             if self.db.get('apt-setup/restricted') == 'false':
  1955.                 use_restricted = False
  1956.         except debconf.DebconfError:
  1957.             len(difference) == 0
  1958.             len(difference) == 0
  1959.         except:
  1960.             len(difference) == 0
  1961.  
  1962.         self.do_remove(difference)
  1963.  
  1964.     
  1965.     def remove_broken_cdrom(self):
  1966.         fstab = os.path.join(self.target, 'etc/fstab')
  1967.         ret = []
  1968.         
  1969.         try:
  1970.             fp = open(fstab)
  1971.             for line in fp:
  1972.                 l = line.split()
  1973.                 if len(l) > 2:
  1974.                     if l[1].startswith('/cdrom') or l[1].startswith('/media/cdrom'):
  1975.                         
  1976.                         try:
  1977.                             fstype = subprocess.Popen([
  1978.                                 'vol_id',
  1979.                                 '--type',
  1980.                                 l[0]], stdout = subprocess.PIPE).communicate()[0].rstrip('\n')
  1981.                             if fstype != 'iso9660' and fstype != 'udf':
  1982.                                 continue
  1983.                         except OSError:
  1984.                             pass
  1985.                         except:
  1986.                             None<EXCEPTION MATCH>OSError
  1987.                         
  1988.  
  1989.                     None<EXCEPTION MATCH>OSError
  1990.                 
  1991.                 ret.append(line)
  1992.             
  1993.             fp.close()
  1994.             fp = open(fstab, 'w')
  1995.             fp.writelines(ret)
  1996.         except Exception:
  1997.             e = None
  1998.             syslog.syslog(syslog.LOG_ERR, 'Exception during installation:')
  1999.             syslog.syslog(syslog.LOG_ERR, 'Unable to process /etc/fstab: ' + str(e))
  2000.         finally:
  2001.             if fp:
  2002.                 fp.close()
  2003.             
  2004.  
  2005.  
  2006.     
  2007.     def cleanup(self):
  2008.         '''Miscellaneous cleanup tasks.'''
  2009.         misc.execute('umount', os.path.join(self.target, 'cdrom'))
  2010.         env = dict(os.environ)
  2011.         env['OVERRIDE_BASE_INSTALLABLE'] = '1'
  2012.         subprocess.call([
  2013.             '/usr/lib/ubiquity/apt-setup/finish-install'], env = env)
  2014.         for apt_conf in ('00NoMountCDROM', '00IgnoreTimeConflict', '00AllowUnauthenticated'):
  2015.             
  2016.             try:
  2017.                 os.unlink(os.path.join(self.target, 'etc/apt/apt.conf.d', apt_conf))
  2018.             continue
  2019.             continue
  2020.  
  2021.         
  2022.         if self.source == '/var/lib/ubiquity/source':
  2023.             self.umount_source()
  2024.         
  2025.  
  2026.     
  2027.     def chrex(self, *args):
  2028.         '''executes commands on chroot system (provided by *args).'''
  2029.         return misc.execute('chroot', self.target, *args)
  2030.  
  2031.     
  2032.     def copy_debconf(self, package):
  2033.         '''setting debconf database into installed system.'''
  2034.         targetdb = os.path.join(self.target, 'var/cache/debconf/config.dat')
  2035.         misc.execute('debconf-copydb', 'configdb', 'targetdb', '-p', '^%s/' % package, '--config=Name:targetdb', '--config=Driver:File', '--config=Filename:' + targetdb)
  2036.  
  2037.     
  2038.     def set_debconf(self, question, value):
  2039.         dccomm = subprocess.Popen([
  2040.             'log-output',
  2041.             '-t',
  2042.             'ubiquity',
  2043.             '--pass-stdout',
  2044.             'chroot',
  2045.             self.target,
  2046.             'debconf-communicate',
  2047.             '-fnoninteractive',
  2048.             'ubiquity'], stdin = subprocess.PIPE, stdout = subprocess.PIPE, close_fds = True)
  2049.         
  2050.         try:
  2051.             dc = debconf.Debconf(read = dccomm.stdout, write = dccomm.stdin)
  2052.             dc.set(question, value)
  2053.             dc.fset(question, 'seen', 'true')
  2054.         finally:
  2055.             dccomm.stdin.close()
  2056.             dccomm.wait()
  2057.  
  2058.  
  2059.     
  2060.     def reconfigure_preexec(self):
  2061.         debconf_disconnect()
  2062.         os.environ['XAUTHORITY'] = '/root/.Xauthority'
  2063.  
  2064.     
  2065.     def reconfigure(self, package):
  2066.         '''executes a dpkg-reconfigure into installed system to each
  2067.         package which provided by args.'''
  2068.         subprocess.call([
  2069.             'log-output',
  2070.             '-t',
  2071.             'ubiquity',
  2072.             'chroot',
  2073.             self.target,
  2074.             'dpkg-reconfigure',
  2075.             '-fnoninteractive',
  2076.             package], preexec_fn = self.reconfigure_preexec, close_fds = True)
  2077.  
  2078.  
  2079. if __name__ == '__main__':
  2080.     if not os.path.exists('/var/lib/ubiquity'):
  2081.         os.makedirs('/var/lib/ubiquity')
  2082.     
  2083.     if os.path.exists('/var/lib/ubiquity/install.trace'):
  2084.         os.unlink('/var/lib/ubiquity/install.trace')
  2085.     
  2086.     install = Install()
  2087.     sys.excepthook = install.excepthook
  2088.     install.run()
  2089.     sys.exit(0)
  2090.  
  2091.